home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / gfx / show / svoUtah22.lha / svoUtahRLE / source / URT / lib / rle_cp.c < prev    next >
C/C++ Source or Header  |  1993-12-22  |  6KB  |  235 lines

  1. /*
  2.  * This software is copyrighted as noted below.  It may be freely copied,
  3.  * modified, and redistributed, provided that the copyright notice is 
  4.  * preserved on all copies.
  5.  * 
  6.  * There is no warranty or other guarantee of fitness for this software,
  7.  * it is provided solely "as is".  Bug reports or fixes may be sent
  8.  * to the author, who may or may not act on them as he desires.
  9.  *
  10.  * You may not include this software in a program or other software product
  11.  * without supplying the source, or without informing the end-user that the 
  12.  * source is available for no extra charge.
  13.  *
  14.  * If you modify this software, you should include a notice giving the
  15.  * name of the person performing the modification, the date of modification,
  16.  * and the reason for such modification.
  17.  */
  18. /* 
  19.  * rle_cp.c - Copy the contents of one RLE image file to another.
  20.  * 
  21.  * Author:    Spencer W. Thomas
  22.  *         EECS Dept.
  23.  *         University of Michigan
  24.  * Date:    Wed Jun 27 1990
  25.  * Copyright (c) 1990, University of Michigan
  26.  */
  27.  
  28. #include <rle.h>
  29. #include <rle_code.h>
  30. #include <rle_put.h>
  31.  
  32. /* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */
  33. #define VAXSHORT( var, fp )\
  34.     { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; }
  35.   
  36. /* Instruction format -- first byte is opcode, second is datum. */
  37.  
  38. #define OPCODE(inst) (inst[0] & ~LONG)
  39. #define LONGP(inst) (inst[0] & LONG)
  40. #define DATUM(inst) (inst[1] & 0xff)    /* Make sure it's unsigned. */
  41.  
  42. /* Write a two-byte value in little_endian order. */
  43. #define    put16(a)    (putc((a)&0xff,outfile),putc(((a)>>8)&0xff,outfile))
  44.  
  45. /*****************************************************************
  46.  * TAG( rle_cp )
  47.  * 
  48.  * Copy the image described by in_hdr to that described by out_hdr
  49.  * until an end-of-image is encountered.
  50.  *
  51.  * Replaces the fread/fwrite loop used that was before we were
  52.  * concerned with concatenated images.
  53.  * 
  54.  * Inputs:
  55.  *     in_hdr:        Describes input image.
  56.  * Outputs:
  57.  *     out_hdr:    Describes output image.
  58.  * Assumptions:
  59.  *     rle_get_setup/rle_put_setup have been called.
  60.  *     in_hdr and out_hdr are compatible -- same number of channels,
  61.  *     same size, all relevant channel bits set.
  62.  *     The scanline most recently read from the input has been
  63.  *     written to the output.
  64.  * Algorithm:
  65.  *     Minimal processing is done.  Each opcode is recognized to the
  66.  *     extent necessary to copy it and its data to the output.
  67.  */
  68. void
  69. rle_cp( in_hdr, the_hdr )
  70. rle_hdr *in_hdr;
  71. rle_hdr *the_hdr;
  72. {
  73.     register FILE *infile = in_hdr->rle_file;
  74.     register FILE *outfile = the_hdr->rle_file;
  75.     char inst[2];
  76.     short nc, buflen;
  77.     char *buffer;
  78.  
  79.     /* Add in vertical skip from last scanline */
  80.     if ( in_hdr->priv.get.vert_skip > 0 )
  81.     {
  82.     in_hdr->priv.get.scan_y += in_hdr->priv.get.vert_skip;
  83.     if ( in_hdr->priv.get.vert_skip > 1 )
  84.         rle_skiprow( the_hdr, in_hdr->priv.get.vert_skip - 1 );
  85.     }
  86.  
  87.     if ( in_hdr->priv.get.is_eof )
  88.     {
  89.     rle_puteof( the_hdr );
  90.     return;
  91.     }
  92.  
  93.     if ( the_hdr->priv.put.nblank > 0 )
  94.     {
  95.     SkipBlankLines( the_hdr->priv.put.nblank );
  96.     the_hdr->priv.put.nblank = 0;
  97.     }
  98.  
  99.     /* Allocate memory for reading byte data. */
  100.     buflen = in_hdr->xmax - in_hdr->xmin + 2;
  101.     buffer = (char *)malloc( buflen );
  102.  
  103.     /* Otherwise, read and write instructions until an EOF
  104.      * instruction is encountered.
  105.      */
  106.     for (;;)
  107.     {
  108.         inst[0] = getc( infile );
  109.     inst[1] = getc( infile );
  110.  
  111.     /* Don't 'put' the instruction until we know what it is. */
  112.     if ( feof(infile) )
  113.     {
  114.         in_hdr->priv.get.is_eof = 1;
  115.         rle_puteof( the_hdr );
  116.         break;        /* <--- one of the exits */
  117.     }
  118.  
  119.     switch( OPCODE(inst) )
  120.     {
  121. #ifdef AMIGA
  122.     char tmp;
  123. #endif
  124.     case RSkipLinesOp:
  125.         putc( inst[0], outfile );
  126.         putc( inst[1], outfile );
  127.         if ( LONGP(inst) )
  128.         {
  129. #ifdef AMIGA
  130.         tmp = getc( infile );
  131.         putc( tmp, outfile );
  132.         tmp = getc( infile );
  133.         putc( tmp, outfile );
  134. #else
  135.         putc( getc( infile ), outfile );
  136.         putc( getc( infile ), outfile );
  137. #endif
  138.         }
  139.         break;            /* need to break for() here, too */
  140.  
  141.     case RSetColorOp:
  142.         putc( inst[0], outfile );
  143.         putc( inst[1], outfile );
  144.         break;
  145.  
  146.     case RSkipPixelsOp:
  147.         putc( inst[0], outfile );
  148.         putc( inst[1], outfile );
  149.         if ( LONGP(inst) )
  150.         {
  151. #ifdef AMIGA
  152.         tmp = getc( infile );
  153.         putc( tmp, outfile );
  154.         tmp = getc( infile );
  155.         putc( tmp, outfile );
  156. #else
  157.         putc( getc( infile ), outfile );
  158.         putc( getc( infile ), outfile );
  159. #endif
  160.         }
  161.         break;
  162.  
  163.     case RByteDataOp:
  164.         putc( inst[0], outfile );
  165.         putc( inst[1], outfile );
  166.         if ( LONGP(inst) )
  167.         {
  168.             VAXSHORT( nc, infile );
  169.         put16( nc );
  170.         }
  171.         else
  172.         nc = DATUM(inst);
  173.         nc++;
  174.         nc = 2 * ((nc + 1) / 2);
  175.         /* Total paranoia.  nc should never be > buflen. */
  176.         while ( nc > buflen )
  177.         {
  178.         fread( buffer, nc, 1, infile );
  179.         fwrite( buffer, nc, 1, outfile );
  180.         nc -= buflen;
  181.         }
  182.  
  183.         fread( buffer, nc, 1, infile );
  184.         fwrite( buffer, nc, 1, outfile );
  185.         break;
  186.  
  187.     case RRunDataOp:
  188.         putc( inst[0], outfile );
  189.         putc( inst[1], outfile );
  190.         if ( LONGP(inst) )
  191.         {
  192. #ifdef AMIGA
  193.         tmp = getc( infile );
  194.         putc( tmp, outfile );
  195.         tmp = getc( infile );
  196.         putc( tmp, outfile );
  197. #else
  198.         putc( getc( infile ), outfile );
  199.         putc( getc( infile ), outfile );
  200. #endif
  201.         }
  202.  
  203. #ifdef AMIGA
  204.         tmp = getc( infile );
  205.         putc( tmp, outfile );
  206.         tmp = getc( infile );
  207.         putc( tmp, outfile );
  208. #else
  209.         putc( getc( infile ), outfile );
  210.         putc( getc( infile ), outfile );
  211. #endif
  212.         break;
  213.  
  214.     case REOFOp:
  215.         in_hdr->priv.get.is_eof = 1;
  216.         rle_puteof( the_hdr );
  217.         break;
  218.  
  219.     default:
  220.         fprintf( stderr, "rle_cp: Unrecognized opcode: %d\n",
  221.              OPCODE(inst) );
  222.         fflush( the_hdr->rle_file );
  223.         exit(1);
  224.     }
  225.     if ( OPCODE(inst) == REOFOp )
  226.         break;            /* <--- the other loop exit */
  227.     }
  228.  
  229.     /* Just in case the caller does something silly like calling rle_getrow. */
  230.     in_hdr->priv.get.scan_y = in_hdr->ymax;
  231.     in_hdr->priv.get.vert_skip = 0;
  232.  
  233.     return;
  234. }
  235.